package com.lg.tochat.config;

import dev.langchain4j.community.store.embedding.redis.RedisEmbeddingStore;
import dev.langchain4j.data.document.Document;
import dev.langchain4j.data.document.loader.ClassPathDocumentLoader;
import dev.langchain4j.memory.ChatMemory;
import dev.langchain4j.memory.chat.ChatMemoryProvider;
import dev.langchain4j.memory.chat.MessageWindowChatMemory;
import dev.langchain4j.model.embedding.EmbeddingModel;
import dev.langchain4j.model.openai.OpenAiChatModel;
import dev.langchain4j.rag.content.retriever.ContentRetriever;
import dev.langchain4j.rag.content.retriever.EmbeddingStoreContentRetriever;
import dev.langchain4j.store.embedding.EmbeddingStore;
import dev.langchain4j.store.embedding.EmbeddingStoreIngestor;
import dev.langchain4j.store.memory.chat.ChatMemoryStore;
import jakarta.annotation.Resource;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

import java.util.List;

@Configuration
public class commonConfig {
    @Resource
    private OpenAiChatModel model;
    @Resource
    private ChatMemoryStore RedisChatMemoryStore;
    @Resource
    private EmbeddingModel embeddingModel;
    @Resource
    private RedisEmbeddingStore redisEmbeddingStore;
//    @Bean
//    public ConsultantService consultantService(){
//        ConsultantService consultantService =AiServices.builder(ConsultantService.class)
//                .chatModel(model)
//                .build();
//        return consultantService;
//    }


    //会话记忆对象
    @Bean
    public ChatMemory chatMemory() {
        ChatMemory chatMemory = MessageWindowChatMemory.builder()
                .id("chatMemory")
                .maxMessages(20)
                .build();
        return chatMemory;
    }

    @Bean
    public ChatMemoryProvider chatMemoryProvider() {
            ChatMemoryProvider chatMemoryProvider = new ChatMemoryProvider() {
            @Override
                public ChatMemory get(Object memoryId) {
                return MessageWindowChatMemory.builder()
                        .id(memoryId)
                        .maxMessages(20)
                        .chatMemoryStore(RedisChatMemoryStore)
                        .build();
            }
        };
        return chatMemoryProvider;
    }
    @Bean
    //构建向量数据库
    public EmbeddingStore store() {
        //加载文档进内存
        List<Document> document = ClassPathDocumentLoader.loadDocuments("content");
//        List<Document> document = ClassPathDocumentLoader.loadDocuments("content",new ApachePdfBoxDocumentParser());
//        构建向量数据库操作对象 操作的是内存版本的向量数据库
//        InMemoryEmbeddingStore store = new InMemoryEmbeddingStore<>();
        //构建rides向量数据库的对象
//        构建一个EmbeddingStoreIngestor对象，完成文本数据切割，向量化，存储
        EmbeddingStoreIngestor ingestor = EmbeddingStoreIngestor.builder()
                //指定向量数据库对象
//                .embeddingStore(store)
                .embeddingStore(redisEmbeddingStore)
                .embeddingModel(embeddingModel)
                .build();
//                分割文档，向量化，存储
                ingestor.ingest(document);
                return redisEmbeddingStore;
    }
    @Bean
    //构建向量数据库检索对象
    public ContentRetriever retriever(EmbeddingStore store){
        EmbeddingStoreContentRetriever retriever = EmbeddingStoreContentRetriever.builder()
//                指定检索对象
                .embeddingStore(redisEmbeddingStore)
                //指定最小相似度
                .minScore(0.5)
                //指定最大返回结果数量
                .maxResults(5)
                .embeddingModel(embeddingModel)
                .build();
        return retriever;
    }
//    文档解析器在默认情况下使用的是ApacheTikaDocumentParser几乎可以解析所有类型的文档。但在纯PDF文档的使用中效果不好
//    所以可以使用指定的解析器ApachePdfBoxDocumentParser专门来解析PDF文档


}
